<template>
    <view>
        <view class="wrapper">
            <view class="handBtn">
                <!-- #ifdef MP-WEIXIN -->
                <!-- <image @click="selectColorEvent('black','#1A1A1A')"
					:src="selectColor === 'black' ? '/static/images/color_black_selected.png' : '/static/images/color_black.png'"
					class="black-select"></image> -->
                <!-- <image @click="selectColorEvent('red','#ca262a')"
					:src="selectColor === 'red' ? '/static/images/color_red_selected.png' : '/static/images/color_red.png'"
					class="red-select"></image> -->
                <!-- #endif -->
                <!-- #ifndef MP-WEIXIN -->
                <!-- <div class="color_pic" :style="{background:lineColor}" @click="showPickerColor=true"></div> -->
                <!-- #endif -->
                <button @click="clear" class="delBtn">清空</button>
                <!-- <button @click="saveCanvasAsImg" class="saveBtn">保存</button> -->
                <!-- <button @click="previewCanvasImg" class="previewBtn">预览</button> -->
                <button @click="undo" class="undoBtn">撤销</button>
                <button @click="subCanvas" class="subBtn">完成</button>
            </view>
            <view class="handCenter">
                <canvas class="handWriting" :disable-scroll="true" @touchstart="uploadScaleStart"
                    @touchmove="uploadScaleMove" @touchend="uploadScaleEnd" canvas-id="handWriting"></canvas>
            </view>
            <view class="handRight">
                <view class="handTitle">请签名</view>
            </view>
            <canvas  :style="{width: canvasHeight +'rpx',height:canvasWidth +'rpx'}"  class="handleRotate" canvas-id="handleRotate"></canvas>
        </view>

        <pickerColor  :isShow="showPickerColor" :bottom="0" @callback='getPickerColor' />
    </view>
</template>

<script>
    import pickerColor from "./pickerColor.vue"
    export default {
        components: {
            pickerColor
        },
        data() {
            return {
                showPickerColor: false,
                ctx: '',
                canvasWidth: 0,
                canvasHeight: 0,
                selectColor: 'black',
                lineColor: '#1A1A1A',
                points: [],
                historyList: [],
                canAddHistory: true,
                getImagePath: () => {
                    return new Promise((resolve) => {
                        uni.canvasToTempFilePath({
                            canvasId: 'handWriting',
                            fileType: 'png',
                            quality: 1, //图片质量
                            success: res => resolve(res.tempFilePath),
                        })
                    })
                },
                toDataURL: void 0,
                requestAnimationFrame: void 0,
            };
        },
        props: { //可用于修改的参数放在props里   也可单独放在外面做成组件调用  传值
            minSpeed: { //画笔最小速度
                type: Number,
                default: 1.5
            },
            minWidth: { //线条最小粗度
                type: Number,
                default: 3,
            },
            maxWidth: { //线条最大粗度
                type: Number,
                default: 10
            },
            openSmooth: { //开启平滑线条（笔锋）
                type: Boolean,
                default: true
            },
            maxHistoryLength: { //历史最大长度
                type: Number,
                default: 20
            },
            maxWidthDiffRate: { //最大差异率
                type: Number,
                default: 20
            },
            bgColor: { //背景色
                type: String,
                default: ''
            },
        },
        onLoad() {
            this.ctx = uni.createCanvasContext("handWriting");
            this.$nextTick(() => {
                uni.createSelectorQuery().select('.handCenter').boundingClientRect(rect => {
                        this.canvasWidth = rect.width;
                        this.canvasHeight = rect.height;
                        this.drawBgColor()
                    })
                    .exec();
            });
        },
        methods: {
            getPickerColor(color) {
                this.showPickerColor = false;
                if (color) {
                    this.lineColor = color;
                }
            },
            // 笔迹开始
            uploadScaleStart(e) {
                this.canAddHistory = true
                this.ctx.setStrokeStyle(this.lineColor)
                this.ctx.setLineCap("round") //'butt'、'round'、'square'
            },
            // 笔迹移动
            uploadScaleMove(e) {
                let temX = e.changedTouches[0].x
                let temY = e.changedTouches[0].y
                this.initPoint(temX, temY)
                this.onDraw()
            },
            /**
             * 触摸结束
             */
            uploadScaleEnd() {
                this.canAddHistory = true;
                this.points = [];
            },
            /**
             * 记录点属性
             */
            initPoint(x, y) {
                var point = {
                    x: x,
                    y: y,
                    t: Date.now()
                };
                var prePoint = this.points.slice(-1)[0];
                if (prePoint && (prePoint.t === point.t || prePoint.x === x && prePoint.y === y)) {
                    return;
                }
                if (prePoint && this.openSmooth) {
                    var prePoint2 = this.points.slice(-2, -1)[0];
                    point.distance = Math.sqrt(Math.pow(point.x - prePoint.x, 2) + Math.pow(point.y - prePoint.y, 2));
                    point.speed = point.distance / (point.t - prePoint.t || 0.1);
                    point.lineWidth = this.getLineWidth(point.speed);
                    if (prePoint2 && prePoint2.lineWidth && prePoint.lineWidth) {
                        var rate = (point.lineWidth - prePoint.lineWidth) / prePoint.lineWidth;
                        var maxRate = this.maxWidthDiffRate / 100;
                        maxRate = maxRate > 1 ? 1 : maxRate < 0.01 ? 0.01 : maxRate;
                        if (Math.abs(rate) > maxRate) {
                            var per = rate > 0 ? maxRate : -maxRate;
                            point.lineWidth = prePoint.lineWidth * (1 + per);
                        }
                    }
                }
                this.points.push(point);
                this.points = this.points.slice(-3);
            },
            /**
             * @param {Object} 
             * 线宽
             */
            getLineWidth(speed) {
                var minSpeed = this.minSpeed > 10 ? 10 : this.minSpeed < 1 ? 1 : this.minSpeed; //1.5
                var addWidth = (this.maxWidth - this.minWidth) * speed / minSpeed;
                var lineWidth = Math.max(this.maxWidth - addWidth, this.minWidth);
                return Math.min(lineWidth, this.maxWidth);
            },
            /**
             * 绘画逻辑
             */
            onDraw() {
                if (this.points.length < 2) return;
                this.addHistory();
                var point = this.points.slice(-1)[0];
                var prePoint = this.points.slice(-2, -1)[0];
                let that = this
                var onDraw = function onDraw() {
                    if (that.openSmooth) {
                        that.drawSmoothLine(prePoint, point);
                    } else {
                        that.drawNoSmoothLine(prePoint, point);
                    }
                };
                if (typeof this.requestAnimationFrame === 'function') {
                    this.requestAnimationFrame(function() {
                        return onDraw();
                    });
                } else {
                    onDraw();
                }
            },
            //添加历史图片地址
            addHistory() {
                if (!this.maxHistoryLength || !this.canAddHistory) return;
                this.canAddHistory = false;
                if (!this.getImagePath) {
                    this.historyList.length++;
                    return;
                }
                //历史地址 (暂时无用)
                let that = this
                that.getImagePath().then(function(url) {
                    if (url) {
                        that.historyList.push(url)
                        that.historyList = that.historyList.slice(-that.maxHistoryLength);
                    }
                });
            },
            //画平滑线
            drawSmoothLine(prePoint, point) {
                var dis_x = point.x - prePoint.x;
                var dis_y = point.y - prePoint.y;

                if (Math.abs(dis_x) + Math.abs(dis_y) <= 2) {
                    point.lastX1 = point.lastX2 = prePoint.x + dis_x * 0.5;
                    point.lastY1 = point.lastY2 = prePoint.y + dis_y * 0.5;
                } else {
                    point.lastX1 = prePoint.x + dis_x * 0.3;
                    point.lastY1 = prePoint.y + dis_y * 0.3;
                    point.lastX2 = prePoint.x + dis_x * 0.7;
                    point.lastY2 = prePoint.y + dis_y * 0.7;
                }
                point.perLineWidth = (prePoint.lineWidth + point.lineWidth) / 2;
                if (typeof prePoint.lastX1 === 'number') {
                    this.drawCurveLine(prePoint.lastX2, prePoint.lastY2, prePoint.x, prePoint.y, point.lastX1, point
                        .lastY1, point.perLineWidth);
                    if (prePoint.isFirstPoint) return;
                    if (prePoint.lastX1 === prePoint.lastX2 && prePoint.lastY1 === prePoint.lastY2) return;
                    var data = this.getRadianData(prePoint.lastX1, prePoint.lastY1, prePoint.lastX2, prePoint.lastY2);
                    var points1 = this.getRadianPoints(data, prePoint.lastX1, prePoint.lastY1, prePoint.perLineWidth /
                        2);
                    var points2 = this.getRadianPoints(data, prePoint.lastX2, prePoint.lastY2, point.perLineWidth / 2);
                    this.drawTrapezoid(points1[0], points2[0], points2[1], points1[1]);
                } else {
                    point.isFirstPoint = true;
                }
            },
            //画不平滑线
            drawNoSmoothLine(prePoint, point) {
                point.lastX = prePoint.x + (point.x - prePoint.x) * 0.5;
                point.lastY = prePoint.y + (point.y - prePoint.y) * 0.5;
                if (typeof prePoint.lastX === 'number') {
                    this.drawCurveLine(prePoint.lastX, prePoint.lastY, prePoint.x, prePoint.y, point.lastX, point.lastY,
                        this.maxWidth);
                }
            },
            //画线
            drawCurveLine(x1, y1, x2, y2, x3, y3, lineWidth) {
                lineWidth = Number(lineWidth.toFixed(1));
                this.ctx.setLineWidth && this.ctx.setLineWidth(lineWidth);
                this.ctx.lineWidth = lineWidth;
                this.ctx.beginPath();
                this.ctx.moveTo(Number(x1.toFixed(1)), Number(y1.toFixed(1)));
                this.ctx.quadraticCurveTo(Number(x2.toFixed(1)), Number(y2.toFixed(1)), Number(x3.toFixed(1)), Number(y3
                    .toFixed(1)));
                this.ctx.stroke();
                this.ctx.draw && this.ctx.draw(true);
            },
            //画梯形
            drawTrapezoid(point1, point2, point3, point4) {
                this.ctx.beginPath();
                this.ctx.moveTo(Number(point1.x.toFixed(1)), Number(point1.y.toFixed(1)));
                this.ctx.lineTo(Number(point2.x.toFixed(1)), Number(point2.y.toFixed(1)));
                this.ctx.lineTo(Number(point3.x.toFixed(1)), Number(point3.y.toFixed(1)));
                this.ctx.lineTo(Number(point4.x.toFixed(1)), Number(point4.y.toFixed(1)));
                this.ctx.setFillStyle && this.ctx.setFillStyle(this.lineColor);
                this.ctx.fillStyle = this.lineColor;
                this.ctx.fill();
                this.ctx.draw && this.ctx.draw(true);
            },
            //获取弧度
            getRadianData(x1, y1, x2, y2) {
                var dis_x = x2 - x1;
                var dis_y = y2 - y1;
                if (dis_x === 0) {
                    return {
                        val: 0,
                        pos: -1
                    };
                }
                if (dis_y === 0) {
                    return {
                        val: 0,
                        pos: 1
                    };
                }
                var val = Math.abs(Math.atan(dis_y / dis_x));
                if (x2 > x1 && y2 < y1 || x2 < x1 && y2 > y1) {
                    return {
                        val: val,
                        pos: 1
                    };
                }
                return {
                    val: val,
                    pos: -1
                };
            },
            //获取弧度点
            getRadianPoints(radianData, x, y, halfLineWidth) {
                if (radianData.val === 0) {
                    if (radianData.pos === 1) {
                        return [{
                            x: x,
                            y: y + halfLineWidth
                        }, {
                            x: x,
                            y: y - halfLineWidth
                        }];
                    }
                    return [{
                        y: y,
                        x: x + halfLineWidth
                    }, {
                        y: y,
                        x: x - halfLineWidth
                    }];
                }
                var dis_x = Math.sin(radianData.val) * halfLineWidth;
                var dis_y = Math.cos(radianData.val) * halfLineWidth;
                if (radianData.pos === 1) {
                    return [{
                        x: x + dis_x,
                        y: y + dis_y
                    }, {
                        x: x - dis_x,
                        y: y - dis_y
                    }];
                }
                return [{
                    x: x + dis_x,
                    y: y - dis_y
                }, {
                    x: x - dis_x,
                    y: y + dis_y
                }];
            },
            /**
             * 背景色
             */
            drawBgColor() {
                if (!this.bgColor) return;
                this.ctx.setFillStyle && this.ctx.setFillStyle(this.bgColor);
                this.ctx.fillStyle = this.bgColor;
                this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
                this.ctx.draw && this.ctx.draw(true);
            },
            //图片绘制
            drawByImage(url) {
                this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
                try {
                    this.ctx.drawImage(url, 0, 0, this.canvasWidth, this.canvasHeight);
                    this.ctx.draw && this.ctx.draw(true);
                } catch (e) {
                    this.historyList.length = 0;
                }
            },
            /**
             * 清空
             */
            clear() {
                this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
                this.ctx.draw && this.ctx.draw();
                this.drawBgColor();
                this.historyList.length = 0;
            },
            //撤消
            undo() {
                if (!this.getImagePath || !this.historyList.length) return;
                var pngURL = this.historyList.splice(-1)[0];
                this.drawByImage(pngURL);
                if (this.historyList.length === 0) {
                    this.clear();
                }
            },
            //是否为空
            isEmpty() {
                return this.historyList.length === 0;
            },
            /**
             * @param {Object} str
             * @param {Object} color
             * 选择颜色
             */
            selectColorEvent(str, color) {
                this.selectColor = str;
                this.lineColor = color;
                this.ctx.setStrokeStyle(this.lineColor)
            },
            //完成
            subCanvas() {
                let vm = this
                if (this.isEmpty()) {
                    uni.showToast({
                        title: '没有任何绘制内容哦',
                        icon: 'none',
                    });
                    return
                }
                uni.canvasToTempFilePath({
                    canvasId: 'handWriting',
                    fileType: 'png',
                    quality: 1, //图片质量
                    success:  function(res) {
                        let tempPath = res.tempFilePath;
                        // 将图片保存成横向图片
                        const ctx = uni.createCanvasContext('handleRotate', vm);
                        // 由于缩小到一半，所以都需要 /2
                        ctx.translate(0, vm.canvasWidth / 2); // 修改原点坐标（这里是已左上角为坐标原点）
                        ctx.rotate((-90 * Math.PI) / 180); // 逆时针旋转90度
                        ctx.drawImage(tempPath, 0, 0, vm.canvasWidth / 2, vm.canvasHeight / 2);
                        ctx.draw();
                        uni.canvasToTempFilePath({
                            canvasId: 'handleRotate',
                            success: async function(data) {
                                //这是签名图片文件的本地临时地址
                                let path = data.tempFilePath;
                                const result = await vm.$api.uploadImg({filePath:data.tempFilePath})
                                uni.$emit('getQiaming',result)
                                uni.navigateBack()
                                },
                        })
                        //保存到系统相册

                    }
                });
            },
            rotateImg(img) {
                let vm = this
                let canvas = uni.createCanvasContext("handleRotate")
                canvas.save();

                // 设置旋转中心点为canvas中心
                // canvas.translate(canvas.canvasWidth / 2, canvas.canvasHeight / 2);
                // // 设置旋转角度（顺时针旋转90度）
                // canvas.rotate(90 * Math.PI / 180);
                // 绘制图片
                canvas.drawImage(img, 0, 0, img.height, img.width);

                // 恢复之前保存的canvas状态
                canvas.restore();

                // 绘制canvas到视图
                canvas.draw();
                //     ctxs.translate(0, this.canvasHeight);

                //       ctxs.rotate(90 * Math.PI / 180)

                //       ctxs.drawImage(src, 0, 0,this.canvasHeight, this.canvasWidth, )

                //       ctxs.draw()  
                setTimeout(() => {
                    uni.canvasToTempFilePath({
                        canvasId: 'handleRotate',
                        fileType: 'png',
                        quality: 1, //图片质量
                        success: async function(res) {
                            const result = await vm.$api.uploadImg({
                                filePath: res.tempFilePath
                            })
                            uni.$emit('getQiaming', result)
                            uni.navigateBack()
                            //保存到系统相册

                        }
                    });
                }, 1000)



            },
            handleConfirm: function() {
                if (tempPoint.length == 0) {
                    uni.showToast({
                        title: '请先签名',
                        icon: 'none',
                        duration: 2000
                    });
                    return;
                }

                uni.canvasToTempFilePath({
                    canvasId: 'mycanvas',
                    success: function(res) {
                        let tempPath = res.tempFilePath;
                        // 将图片保存成横向图片
                        const ctx = uni.createCanvasContext('camCacnvs', that);
                        // 由于缩小到一半，所以都需要 /2
                        ctx.translate(0, that.width / 2); // 修改原点坐标（这里是已左上角为坐标原点）
                        ctx.rotate((-90 * Math.PI) / 180); // 逆时针旋转90度
                        ctx.drawImage(tempPath, 0, 0, that.width / 2, that.height / 2);
                        ctx.draw();
                        setTimeout(() => {
                            //保存签名图片到本地
                            uni.canvasToTempFilePath({
                                canvasId: 'camCacnvs',
                                success: function(res) {
                                    //这是签名图片文件的本地临时地址
                                    let path = res.tempFilePath;
                                    plus.io.resolveLocalFileSystemURL(path,
                                        function(entry) {
                                            entry.file(function(file) {
                                                var fileReader =
                                                    new plus.io
                                                    .FileReader
                                                fileReader.onload =
                                                    function(evt) {
                                                        // console.log('onload', evt.target.result);
                                                        base64String =
                                                            evt.target
                                                            .result;

                                                    }
                                                fileReader.onerror =
                                                    function(error) {
                                                        console.error(
                                                            'failed',
                                                            error)
                                                    }
                                                fileReader
                                                    .readAsDataURL(
                                                    file);

                                            }, function(error) {
                                                console.error('failed',
                                                    error)
                                            })
                                        },
                                        function(error) {
                                            console.error('failed', error)
                                        })
                                },
                                fail: err => {
                                    console.log('fail', err);
                                }
                            }, );
                        }, 200);

                    }
                });
                return
                // 延迟操作是因为有可能图片 还没 保存下来
                setTimeout(() => {
                    // 这里要用 this
                    that.userInfo.elecSign = base64String;
                    //  将base64 保存或更新起来
                    uni.request({
                        url: your_upload_url,
                        data: {
                            elecSign: base64String,
                        },
                        header: {
                            'content-type': 'application/x-www-form-urlencoded'
                        },
                        method: "POST",
                        success: (res) => {
                            if (res.statusCode == 200) { //请求地址成功
                                if (res.data.code == 200) { //请求方法成功

                                    uni.showToast({
                                        title: "保存成功",
                                        position: "bottom"
                                    });

                                } else {}
                            } else {
                                uni.showToast({
                                    title: "保存失败",
                                    position: "bottom"
                                });
                            }
                        },
                        fail: () => {},
                        complete: () => {}
                    });
                }, 2000)
            },
            //保存到相册
            saveCanvasAsImg() {
                uni.canvasToTempFilePath({
                    canvasId: 'handWriting',
                    fileType: 'png',
                    quality: 1, //图片质量
                    success(res) {
                        uni.saveImageToPhotosAlbum({
                            filePath: res.tempFilePath,
                            success(res) {
                                uni.showToast({
                                    title: '已保存到相册',
                                    duration: 2000
                                });
                            }
                        });
                    }
                });
            },
            //预览
            previewCanvasImg() {
                uni.canvasToTempFilePath({
                    canvasId: 'handWriting',
                    fileType: 'jpg',
                    quality: 1, //图片质量
                    success(res) {
                        uni.previewImage({
                            urls: [res.tempFilePath] //预览图片 数组
                        });
                    }
                });
            },
        }
    };
</script>

<style>
    page {
        background: #fbfbfb;
        height: auto;
        overflow: hidden;
    }

    .wrapper {
        width: 100%;
        height: 95vh;
        margin: 40rpx 0;
        overflow: hidden;
        display: flex;
        align-content: center;
        flex-direction: row;
        justify-content: center;
        font-size: 28rpx;
    }

    .handWriting {
        background: #fff;
        width: 100%;
        height: 95vh;
    }

    .handleRotate {
        position: absolute;
        left: -200000rpx;
        top: -4400000rpx;
      /*  height: 316px;
        width: 793px; */
    }

    .handRight {
        display: inline-flex;
        align-items: center;
    }

    .handCenter {
        border: 4rpx dashed #e9e9e9;
        flex: 5;
        overflow: hidden;
        display: flex;
        align-items: center;
        box-sizing: border-box;
    }

    .handTitle {
        transform: rotate(90deg);
        flex: 1;
        color: #666;
    }

    .handBtn button {
        font-size: 28rpx;
    }

    .handBtn {
        height: 95vh;
        display: inline-flex;
        flex-direction: column;
        justify-content: space-between;
        align-content: space-between;
        flex: 1;
    }

    .delBtn {
        position: absolute;
        top: 250rpx;
        left: 0rpx;
        transform: rotate(90deg);
        color: #666;
    }

    .delBtn image {
        position: absolute;
        top: 13rpx;
        left: 25rpx;
    }

    .subBtn {
        position: absolute;
        bottom: 52rpx;
        left: -3rpx;
        display: inline-flex;
        transform: rotate(90deg);
        background: #008ef6;
        color: #fff;
        margin-bottom: 30rpx;
        text-align: center;
        justify-content: center;
    }

    /*Peach - 新增 - 保存*/

    .saveBtn {
        position: absolute;
        top: 375rpx;
        left: 0rpx;
        transform: rotate(90deg);
        color: #666;
    }

    .previewBtn {
        position: absolute;
        top: 500rpx;
        left: 0rpx;
        transform: rotate(90deg);
        color: #666;
    }

    .undoBtn {
        position: absolute;
        top: 625rpx;
        left: 0rpx;
        transform: rotate(90deg);
        color: #666;
    }

    .black-select {
        width: 60rpx;
        height: 60rpx;
        position: absolute;
        top: 30rpx;
        left: 25rpx;
    }

    .red-select {
        width: 60rpx;
        height: 60rpx;
        position: absolute;
        top: 140rpx;
        left: 25rpx;
    }

    .color_pic {
        width: 70rpx;
        height: 70rpx;
        border-radius: 25px;
        position: absolute;
        top: 60rpx;
        left: 18rpx;
        border: 1px solid #ddd;
    }
</style>